package cn.reach.rpc.future;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @Author: ReachYin
 * @Date: 2025/7/2 13:55
 * @Version: v1.0.0
 * @Description: Future对象
 **/
public class DefaultFuture<R> {
    // 创建锁与条件变量
    private final Lock lock = new ReentrantLock();
    private final Condition done = lock.newCondition();
    private R response;
    private Throwable exception; // 添加异常字段
    private long startTime; // 记录开始时间
    private volatile boolean cancelled; // 是否被取消
    
    public DefaultFuture() {
        this.startTime = System.currentTimeMillis();
    }
    
    // 调用方通过该方法等待结果
    public R get(int timeout) throws TimeoutException, InterruptedException {
        return get(timeout, TimeUnit.MILLISECONDS);
    }
    
    // 增加TimeUnit参数的重载方法
    public R get(long timeout, TimeUnit unit) throws TimeoutException, InterruptedException {
        long timeoutMillis = unit.toMillis(timeout);
        long start = System.currentTimeMillis();
        lock.lock();
        try {
            while (!isDone()) {
                done.await(timeoutMillis, TimeUnit.MILLISECONDS);
                long elapsed = System.currentTimeMillis() - start;
                if (isDone() || elapsed > timeoutMillis) {
                    break;
                }
                // 更新剩余等待时间
                timeoutMillis -= elapsed;
            }
        } finally {
            lock.unlock();
        }
        
        if (!isDone()) {
            throw new TimeoutException("等待响应超时");
        }
        
        if (exception != null) {
            throw new RuntimeException("远程调用异常", exception);
        }
        
        return response;
    }
    
    // 是否完成
    public boolean isDone() {
        return response != null || exception != null || cancelled;
    }
    
    // 取消操作
    public boolean cancel() {
        lock.lock();
        try {
            if (!isDone()) {
                cancelled = true;
                done.signalAll();
                return true;
            }
            return false;
        } finally {
            lock.unlock();
        }
    }
    
    // 是否被取消
    public boolean isCancelled() {
        return cancelled;
    }
    
    // 获取等待时间
    public long getElapsedTimeMillis() {
        return System.currentTimeMillis() - startTime;
    }
    
    // 设置正常结果
    public void doReceived(R res) {
        lock.lock();
        try {
            if (!isDone()) {
                response = res;
                done.signalAll();
            }
        } finally {
            lock.unlock();
        }
    }
    
    // 设置异常结果
    public void setException(Throwable t) {
        lock.lock();
        try {
            if (!isDone()) {
                exception = t;
                done.signalAll();
            }
        } finally {
            lock.unlock();
        }
    }
}
